package online.sixfish.question.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import online.sixfish.common.utils.SecurityUtil;
import online.sixfish.question.mapper.MockMatchRecordMapper;
import online.sixfish.question.model.entity.MockMatchRecord;
import online.sixfish.question.model.entity.QueProgram;
import online.sixfish.question.model.vo.MockMatchReq;
import online.sixfish.question.model.vo.QueProgramVO;
import online.sixfish.question.service.QueProgramService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Service
public class MockMatchServiceImpl implements MockMatchService {
    @Resource
    QueProgramService queProgramService;

    @Resource
    MockMatchRecordMapper mockMatchRecordMapper;


    @Override
    public Integer currentMatchId() {
        LambdaQueryWrapper<MockMatchRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MockMatchRecord::getStatus, 1);
        wrapper.eq(MockMatchRecord::getUserId, SecurityUtil.currentUserId());

        MockMatchRecord record = mockMatchRecordMapper.selectOne(wrapper);
        if (Objects.isNull(record)) {
            return null;
        }
        return record.getId();
    }


    @Override
    public Integer start(MockMatchReq req) {
        //1.选择题目
        Set<QueProgram> quePrograms = chooseQuestion(req.getQuestionNum());
        //2.保存数据库记录
        if(Objects.nonNull(req.getTime())){
            req.setTime(60);
        }
        MockMatchRecord record = insert2Db(quePrograms, req.getTime());
        return record.getId();

    }

    @Override
    public List<QueProgramVO> questionList(Integer id) {
        MockMatchRecord record = mockMatchRecordMapper.selectById(id);
        String list = record.getQuestionList();
        List<Integer> questionIds = JSON.parseArray(list, Integer.class);
        List<QueProgramVO> programs = questionIds.stream()
                .map(p -> {
                    QueProgram queProgram = queProgramService.getById(p);
                    QueProgramVO programVO = new QueProgramVO();
                    BeanUtils.copyProperties(queProgram, programVO);
                    return programVO;
                }).collect(Collectors.toList());
        return programs;
    }

    @Override
    public MockMatchRecord findById(Integer id) {
        return mockMatchRecordMapper.selectById(id);
    }

    @Override
    public void schedule() {
        LambdaQueryWrapper<MockMatchRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MockMatchRecord::getStatus,1);

        List<MockMatchRecord> mockMatchRecords = mockMatchRecordMapper
                .selectList(wrapper);
        mockMatchRecords.stream().forEach(m -> {
                    int timePeriod = m.getTimeMinute() * 1000 * 60;
                    if (System.currentTimeMillis() - m.getCreateTime().getTime() > timePeriod) {
                        MockMatchRecord record = new MockMatchRecord();
                        record.setId(m.getId());
                        record.setStatus(3);
                        mockMatchRecordMapper.updateById(record);
                        log.info("修改模拟赛场状态成功");
                    }

                }

        );
    }


    private MockMatchRecord insert2Db(Set<QueProgram> quePrograms, Integer times) {
        MockMatchRecord record = new MockMatchRecord();

        record.setUserId(SecurityUtil.currentUserId());
        List<Integer> questionIds = new ArrayList<>();
        quePrograms.forEach(queProgram -> {
            questionIds.add(queProgram.getId());
        });
        record.setQuestionList(JSON.toJSONString(questionIds));
        record.setCreateTime(new Date());
        record.setTimeMinute(times);
        mockMatchRecordMapper.insert(record);
        return record;
    }

    private Set<QueProgram> chooseQuestion(Integer questionNum) {
        Set<QueProgram> quePrograms = new HashSet<>();
        while (quePrograms.size() < questionNum) {
            Random random = new Random();
            int i = random.nextInt(queProgramService.getTotal()) + 1;
            QueProgram queProgram = queProgramService.getById(i);
            if (Objects.nonNull(queProgram)) {
                quePrograms.add(queProgram);
            }
        }
        return quePrograms;

    }


}
